﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
using System.Windows.Controls;
using System.Windows;
using System.Windows.Media;
using System.Windows.Shapes;
using System.Reflection;

namespace CandleStickChart.Stock
{
    public class DataCollection
    {
        #region Fields & Properties
       
        private ObservableCollection<DataSeries> _dataList;
        public ObservableCollection<DataSeries> DataList
        {
            get { return _dataList; }
            set { _dataList = value; }
        }
        private StockChartTypeEnum stockChartType =
                                   StockChartTypeEnum.HiLoOpenClose;

        public StockChartTypeEnum StockChartType
        {
            get { return stockChartType; }
            set { stockChartType = value; }
        }
        #endregion
        
        public DataCollection()
        {
            _dataList = new ObservableCollection<DataSeries>();
        }


        public void AddStockChart(ChartStyle cs)
        {
            foreach (DataSeries  ds in DataList)
            {
                double barWidth = cs.ChartCanvas.Width / (5 * ds.DataItems.Count);
                double d0 = cs.DateToDouble(ds.DataItems[0].Date.ToShortDateString());
                double d1 = cs.DateToDouble(ds.DataItems[1].Date.ToShortDateString());
                ObservableCollection<StockItemConverted> stockData = new ObservableCollection<StockItemConverted>();

                for (int i = 0; i < ds.DataItems.Count; i++)
                {
                    StockItemConverted converted = new StockItemConverted();

                    if (d0 > d1)
                    {
                        converted.High = ds.DataItems[ds.DataItems.Count - 1 - i].High;
                        converted.Open = ds.DataItems[ds.DataItems.Count - 1 - i].Open;
                        converted.Low = ds.DataItems[ds.DataItems.Count - 1 - i].Low;
                        converted.Close = ds.DataItems[ds.DataItems.Count - 1 - i].Close;

                    }
                    else
                    {
                       // converted.Date = cs.DateToDouble(stockItem.Date.ToShortDateString());
                        converted.High = ds.DataItems[i].High;
                        converted.Close = ds.DataItems[i].Close;
                        converted.Low = ds.DataItems[i].Low;
                        converted.Open = ds.DataItems[i].Open;
                    }
                    stockData.Add(converted);
                }
                for(int i = 0; i<ds.DataItems.Count;i++)
                {
                    Point ptHigh = cs.NormalizePoint(new Point(i, stockData[i].High));
                    Point ptLow = cs.NormalizePoint(new Point(i, stockData[i].Low));
                    Point ptOpen = cs.NormalizePoint(new Point(i, stockData[i].Open));
                    Point ptClose = cs.NormalizePoint(new Point(i, stockData[i].Close));

                    Point ptOpen1 = new Point(ptOpen.X-barWidth,ptOpen.Y);
                    Point ptClose1 = new Point(ptClose.X + barWidth,ptClose.Y);
                    Point ptOpen2 = new Point(ptOpen.X + barWidth, ptOpen.Y);
                    Point ptClose2 = new Point(ptClose.X - barWidth, ptClose.Y);

                    switch (StockChartType)
                    {
                        case StockChartTypeEnum.HiLo:
                            {
                                DrawLine(cs.ChartCanvas, ptLow, ptHigh, ds.LineColor, ds.LineThickness);
                                break;
                            }
                        case StockChartTypeEnum.HiLoOpenClose:
                            {
                                DrawLine(cs.ChartCanvas, ptLow, ptHigh, ds.LineColor, ds.LineThickness);
                                DrawLine(cs.ChartCanvas, ptOpen, ptOpen1, ds.LineColor, ds.LineThickness);
                                DrawLine(cs.ChartCanvas, ptClose, ptClose1, ds.LineColor, ds.LineThickness);
                                break;
                            }
                        case StockChartTypeEnum.Candle:
                            {
                                DrawLine(cs.ChartCanvas, ptLow, ptHigh, ds.LineColor, ds.LineThickness);
                                Polygon plg = new Polygon();
                                plg.Stroke = ds.LineColor;
                                plg.StrokeThickness = ds.LineThickness;
                                Brush fillColor = ds.FillColor;
                                if(stockData[i].Open < stockData[i].Close )
                                    fillColor = Brushes.White;
                                plg.Fill = fillColor;
                                plg.Points.Add(ptOpen1);
                                plg.Points.Add(ptOpen2);
                                plg.Points.Add(ptClose1);
                                plg.Points.Add(ptClose2);
                                cs.ChartCanvas.Children.Add(plg);
                                break;
                            }
                        case StockChartTypeEnum.Line:
                            {
                                if (i > 0)
                                {
                                    Point pt1 = cs.NormalizePoint(new Point(i-1,stockData[i-1].Close));
                                    Point pt2 = cs.NormalizePoint(new Point(i, stockData[i].Close));
                                    DrawLine(cs.ChartCanvas, pt1, pt2, ds.LineColor, ds.LineThickness);
                                }
                                break;

                            }
                        default:
                            break;
                    }
                }
            }
        }

        // Adds and Draws a new DataSeries object onto the Chart
        public void AddNewPoin(ChartStyle cs, DataSeries ds, StockItem item)
        {
            ds.DataItems.Insert(0,item);
            this.AddStockChart(cs);
        }

        private void DrawLine(Canvas canvas, Point pt1, Point pt2,
                              Brush lineColor, double lineThickness)
        {
            Line line = new Line();
            line.Stroke = lineColor;
            line.StrokeThickness = lineThickness;
            line.X1 = pt1.X;
            line.Y1 = pt1.Y;
            line.X2 = pt2.X;
            line.Y2 = pt2.Y;
            canvas.Children.Add(line);
        }
        public enum StockChartTypeEnum
        {
            HiLo = 0,
            HiLoOpenClose = 1,
            Candle = 2,
            Line = 3
        }
    }
}
